/**
* +----------------------------------------------------------------------
* | 友得云客  - 开启房产营销新纪元
* +----------------------------------------------------------------------
* | Copyright (c) 2019~2023 优得（西安）信息科技有限公司版权所有
* +----------------------------------------------------------------------
* | Licensed 友得云客不是自由软件 未经允许不可移除相关版权
* +----------------------------------------------------------------------
* | Author: www.youdeyunke.com
* +----------------------------------------------------------------------
*/
import Vue from 'vue'
import { mergeRecursive } from "@/utils/ruoyi";
import DictMeta from './DictMeta'
import DictData from './DictData'

const DEFAULT_DICT_OPTIONS = {
    types: [],
}

/**
 * @classdesc 字典
 * @property {Object} label 标签对象，内部属性名为字典类型名称
 * @property {Object} dict 字段数组，内部属性名为字典类型名称
 * @property {Array.<DictMeta>} _dictMetas 字典元数据数组
 */
export default class Dict {
    constructor() {
        this.owner = null
        this.label = {}
        this.type = {}
    }

    init (options) {
        if (options instanceof Array) {
            options = { types: options }
        }
        const opts = mergeRecursive(DEFAULT_DICT_OPTIONS, options)
        if (opts.types === undefined) {
            throw new Error('need dict types')
        }
        const ps = []
        this._dictMetas = opts.types.map(t => DictMeta.parse(t))
        this._dictMetas.forEach(dictMeta => {
            const type = dictMeta.type
            Vue.set(this.label, type, {})
            Vue.set(this.type, type, [])
            if (dictMeta.lazy) {
                return
            }
            ps.push(loadDict(this, dictMeta))
        })
        return Promise.all(ps)
    }

    /**
     * 重新加载字典
     * @param {String} type 字典类型
     */
    reloadDict (type) {
        const dictMeta = this._dictMetas.find(e => e.type === type)
        if (dictMeta === undefined) {
            return Promise.reject(`the dict meta of ${type} was not found`)
        }
        return loadDict(this, dictMeta)
    }
}

/**
 * 加载字典
 * @param {Dict} dict 字典
 * @param {DictMeta} dictMeta 字典元数据
 * @returns {Promise}
 */
function loadDict (dict, dictMeta) {
    return dictMeta.request(dictMeta)
        .then(response => {
            const type = dictMeta.type
            let dicts = dictMeta.responseConverter(response, dictMeta)
            if (!(dicts instanceof Array)) {
                console.error('the return of responseConverter must be Array.<DictData>')
                dicts = []
            } else if (dicts.filter(d => d instanceof DictData).length !== dicts.length) {
                console.error('the type of elements in dicts must be DictData')
                dicts = []
            }
            dict.type[type].splice(0, Number.MAX_SAFE_INTEGER, ...dicts)
            dicts.forEach(d => {
                Vue.set(dict.label[type], d.value, d.label)
            })
            return dicts
        })
}
